package com.zhouyy.common.exception;

import com.zhouyy.common.bean.ValidVo;
import com.zhouyy.common.vo.ApiResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ValidationException;
import java.util.LinkedList;
import java.util.List;

/**
 * <p> 异常处理 </p>
 *
 * @author zhouyy
 * @description
 * @date 2024/03/26 14:42
 */
@RestControllerAdvice
public class CommonExceptionHandler {

    private static final Logger log = LoggerFactory.getLogger(CommonExceptionHandler.class);

    /**
     * 处理api接口异常
     */
    @ExceptionHandler(ApiException.class)
    public ApiResult<String> handleBindException(ApiException ex) {
        return ApiResult.fail(ex.getMessage());
    }

    @ExceptionHandler(ValidationException.class)
    public ApiResult handleValidationException(ValidationException e) {
        log.error("ValidationException:", e);
        Throwable cause = e.getCause();
        if (cause == null) {
            return ApiResult.fail(e.getMessage());
        }
        String message = cause.getMessage();
        return ApiResult.fail(message);
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ApiResult<List<ValidVo>> handleBindException(MethodArgumentNotValidException ex) {
        BindingResult bindingResult = ex.getBindingResult();
        List<ValidVo> validVos = getErrorVo(bindingResult);
        return ApiResult.fail(validVos.get(0).getMsg());
    }

    private List<ValidVo> getErrorVo(BindingResult bindingResult) {
        List<FieldError> fieldErrors = bindingResult.getFieldErrors();
        List<ValidVo> results = new LinkedList<>();
        fieldErrors.forEach(f -> {
            String defaultMessage = f.getDefaultMessage();
            String field = f.getField();
            results.add(new ValidVo(field, defaultMessage));
        });
        return results;
    }


    @ExceptionHandler({Exception.class})
    public ApiResult exception(Exception e) {
        log.error("其他错误:", e);
        return ApiResult.fail(500, "其他错误：" + e);
    }
}